﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Reactive;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using MilkTeaMachine.OfflineClient.EntityFrameworkCore;
using MilkTeaMachine.OfflineClient.EntityFrameworkCore.Models;
using MilkTeaMachine.OfflineClient.Models;
using MilkTeaMachine.OfflineClient.Utils;
using MilkTeaMachine.OfflineClient.Utils.Constants;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Splat;

namespace MilkTeaMachine.OfflineClient.ViewModels;

public partial class FormulaSaveOrUpdateViewModel : ViewModelBase, IRoutableViewModel
{
    private readonly ApplicationDbContext _db;

    //Base
    private FormulaSaveOrUpdateViewModel(IScreen parent, IScreen ancestor)
    {
        HostScreen = parent;
        AncestorScreen = ancestor;
        _db = Locator.Current.GetService<ApplicationDbContext>()!;
        Ingredients = GetIngredientList();
        AllCupTypeObservableCollection = new ObservableCollection<CupVo>(_defaultCupList);
        AllSugarTypeObservableCollection = new ObservableCollection<SugarVo>(_defaultSugarList);
        AllIceTypeObservableCollection = new ObservableCollection<IceVo>(_defaultIceList);
        SelectCupTypeCmd = ReactiveCommand.CreateFromTask(async (CupVo vo) => { await SelectCupTypeAsync(vo); });
        SelectSugarTypeCmd = ReactiveCommand.CreateFromTask(async (SugarVo vo) => { await SelectSugarTypeAsync(vo); });
        SelectIceTypeCmd = ReactiveCommand.CreateFromTask(async (IceVo vo) => { await SelectIceTypeAsync(vo); });
        ToggleAddWaterCmd = ReactiveCommand.CreateFromTask(async (string value) =>
        {
            await ToggleAddWaterAsync(Convert.ToBoolean(value));
        });
        ToggleAddColdWaterCmd = ReactiveCommand.CreateFromTask(async (string value) =>
        {
            await ToggleAddColdWaterAsync(Convert.ToBoolean(value));
        });
        SaveAndQuitCmd = ReactiveCommand.CreateFromTask(async () => { await SaveAndQuitAsync(); },
            this.WhenAnyValue(
                vm => vm.SelectedCupType,
                vm => vm.SelectedSugarType,
                vm => vm.SelectedIceType,
                (t1, t2, t3) => t1 is not null && t2 is not null && t3 is not null));
        GoBackCmd = ReactiveCommand.CreateFromObservable(() =>
            AncestorScreen.Router.NavigateBack.Execute());
    }

    public FormulaSaveOrUpdateViewModel(
        IScreen parent,
        IScreen ancestor,
        ActionTypeEnum actionType,
        int formulaId = default) : this(parent,
        ancestor)
    {
        ActionType = actionType;
        _ = actionType switch
        {
            ActionTypeEnum.新建 => CreateNewFormulaAsync(),
            ActionTypeEnum.修改 => EditFormulaAsync(formulaId),
            ActionTypeEnum.复制新建 => CopyCreateNewFormula(formulaId),
            _ => throw new ArgumentOutOfRangeException(nameof(actionType), actionType, null)
        };
    }

    private ActionTypeEnum ActionType { get; set; }
    private List<FormulaIngredient> _formulaIngredientList = new(8);
    [Reactive] private SugarTypeEnum? SelectedSugarType { get; set; }
    [Reactive] private IceTypeEnum? SelectedIceType { get; set; }
    [Reactive] private CupTypeEnum? SelectedCupType { get; set; }
    public string? UrlPathSegment { get; } = nameof(FormulaSaveOrUpdateViewModel);
    public IScreen HostScreen { get; }
    private IScreen AncestorScreen { get; }
    [Reactive] public FormulaSaveOrUpdateVo FormulaDetail { get; set; } = new();
    [Reactive] public bool IsAddWater { get; set; }
    [Reactive] public bool IsAddColdWater { get; set; }
    [Reactive] public bool IsAddHotWater { get; set; }

    [Reactive] public char CupTypeCode { get; set; } = '-';
    [Reactive] public char IceTypeCode { get; set; } = '-';
    [Reactive] public char SugarTypeCode { get; set; } = '-';
    [Reactive] public string? CustomCode { get; set; }
    private Formula? _formula;
    public List<IngredientAndWeightVo> Ingredients { get; }
    public ObservableCollection<CupVo> AllCupTypeObservableCollection { get; }
    public ReactiveCommand<CupVo, Unit> SelectCupTypeCmd { get; }
    public ObservableCollection<SugarVo> AllSugarTypeObservableCollection { get; }
    public ReactiveCommand<SugarVo, Unit> SelectSugarTypeCmd { get; }
    public ObservableCollection<IceVo> AllIceTypeObservableCollection { get; }
    public ReactiveCommand<IceVo, Unit> SelectIceTypeCmd { get; }
    public ReactiveCommand<string, Unit> ToggleAddWaterCmd { get; }
    public ReactiveCommand<string, Unit> ToggleAddColdWaterCmd { get; }
    public ReactiveCommand<Unit, Unit> SaveAndQuitCmd { get; }
    public ReactiveCommand<Unit, IRoutableViewModel> GoBackCmd { get; }
}

public partial class FormulaSaveOrUpdateViewModel
{
    private Task ToggleAddWaterAsync(bool b)
    {
        FormulaDetail.IsAddWater = b;
        IsAddWater = b;
        if (b)
        {
            FormulaDetail.IsAddColdWater = true;
            IsAddColdWater = true;
        }
        else
        {
            FormulaDetail.IsAddColdWater = false;
            FormulaDetail.IsAddHotWater = false;
            IsAddHotWater = false;
            IsAddColdWater = false;
        }

        return Task.CompletedTask;
    }


    private Task SelectIceTypeAsync(IceVo ice)
    {
        if (ice.IsSelected || ice.IsTitle)
            return Task.CompletedTask;
        ProcessLastSelectedIce();
        ice.IsSelected = true;
        SetIceProperly(ice);
        var pos = AllIceTypeObservableCollection.IndexOf(ice);
        AllIceTypeObservableCollection.Remove(ice);
        AllIceTypeObservableCollection.Insert(pos, ice);
        SelectedIceType = ice.IceType;
        IceTypeCode = Formula.GetIceTypeCode(ice.IceType);
        return Task.CompletedTask;
    }

    private void ProcessLastSelectedIce()
    {
        var lastSelectedItem = AllIceTypeObservableCollection
            .First(vo => vo.IsSelected);
        lastSelectedItem.IsSelected = false;
        var lastSelectedItemIndex = AllIceTypeObservableCollection.IndexOf(lastSelectedItem);
        SetIceProperly(lastSelectedItem);
        AllIceTypeObservableCollection.Remove(lastSelectedItem);
        AllIceTypeObservableCollection.Insert(lastSelectedItemIndex, lastSelectedItem);
    }

    private static void SetIceProperly(IceVo vo)
    {
        if (vo.IsSelected)
            _ = vo.IceType switch
            {
                IceTypeEnum.无冰 when vo.IsTitle => vo.Image = BitmapConstants.IceActive,
                IceTypeEnum.去冰 => vo.Image = BitmapConstants.StripIceActive,
                IceTypeEnum.少冰 => vo.Image = BitmapConstants.LittleIceActive,
                IceTypeEnum.正常 => vo.Image = BitmapConstants.NormalActive,
                IceTypeEnum.常温 => vo.Image = BitmapConstants.NormalTemperatureActive,
                IceTypeEnum.无冰 => vo.Image = BitmapConstants.NoIceActive,
                _ => throw new ArgumentOutOfRangeException()
            };
        else
            _ = vo.IceType switch
            {
                IceTypeEnum.无冰 when vo.IsTitle => vo.Image = BitmapConstants.IceInactive,
                IceTypeEnum.去冰 => vo.Image = BitmapConstants.StripIceInactive,
                IceTypeEnum.少冰 => vo.Image = BitmapConstants.LittleIceInactive,
                IceTypeEnum.正常 => vo.Image = BitmapConstants.NormalInactive,
                IceTypeEnum.常温 => vo.Image = BitmapConstants.NormalTemperatureInactive,
                IceTypeEnum.无冰 => vo.Image = BitmapConstants.NoIceInactive,
                _ => throw new ArgumentOutOfRangeException()
            };
    }

    private Task SelectSugarTypeAsync(SugarVo sugar)
    {
        if (sugar.IsSelected || sugar.IsTitle)
            return Task.CompletedTask;
        ProcessLastSelectedSugar();
        sugar.IsSelected = true;
        SetSugarProperly(sugar);
        var pos = AllSugarTypeObservableCollection.IndexOf(sugar);
        AllSugarTypeObservableCollection.Remove(sugar);
        AllSugarTypeObservableCollection.Insert(pos, sugar);
        SelectedSugarType = sugar.SugarType;
        SugarTypeCode = Formula.GetSugarTypeCode(SelectedSugarType.Value);
        return Task.CompletedTask;
    }

    private void ProcessLastSelectedSugar()
    {
        var lastSelectedItem = AllSugarTypeObservableCollection
            .First(vo => vo.IsSelected);
        lastSelectedItem.IsSelected = false;
        var lastSelectedItemIndex = AllSugarTypeObservableCollection.IndexOf(lastSelectedItem);
        SetSugarProperly(lastSelectedItem);
        AllSugarTypeObservableCollection.Remove(lastSelectedItem);
        AllSugarTypeObservableCollection.Insert(lastSelectedItemIndex, lastSelectedItem);
    }

    private void SetSugarProperly(SugarVo vo)
    {
        if (vo.IsSelected)
            _ = vo.SugarType switch
            {
                SugarTypeEnum.全糖 when vo.IsTitle => vo.Image = BitmapConstants.SugarActive,
                SugarTypeEnum.零糖 => vo.Image = BitmapConstants.NoSugarActive,
                SugarTypeEnum.三分 => vo.Image = BitmapConstants.ThreeSugarActive,
                SugarTypeEnum.五分 => vo.Image = BitmapConstants.FiveSugarActive,
                SugarTypeEnum.七分 => vo.Image = BitmapConstants.SevenSugarActive,
                SugarTypeEnum.全糖 => vo.Image = BitmapConstants.FullSugarActive,
                _ => throw new ArgumentOutOfRangeException()
            };
        else
            _ = vo.SugarType switch
            {
                SugarTypeEnum.全糖 when vo.IsTitle => vo.Image = BitmapConstants.SugarInactive,
                SugarTypeEnum.零糖 => vo.Image = BitmapConstants.NoSugarInactive,
                SugarTypeEnum.三分 => vo.Image = BitmapConstants.ThreeSugarInactive,
                SugarTypeEnum.五分 => vo.Image = BitmapConstants.FiveSugarInactive,
                SugarTypeEnum.七分 => vo.Image = BitmapConstants.SevenSugarInactive,
                SugarTypeEnum.全糖 => vo.Image = BitmapConstants.FullSugarInactive,
                _ => throw new ArgumentOutOfRangeException()
            };
    }

    private Task SelectCupTypeAsync(CupVo cup)
    {
        if (cup.IsSelected || cup.IsTitle)
            return Task.CompletedTask;
        ProcessLastSelectedCup();
        cup.IsSelected = true;
        SetCupProperly(cup);
        var pos = AllCupTypeObservableCollection.IndexOf(cup);
        AllCupTypeObservableCollection.Remove(cup);
        AllCupTypeObservableCollection.Insert(pos, cup);
        SelectedCupType = cup.CupType;
        CupTypeCode = Formula.GetCupTypeCode(cup.CupType);
        return Task.CompletedTask;
    }

    private void ProcessLastSelectedCup()
    {
        var lastSelectedItem = AllCupTypeObservableCollection
            .First(vo => vo.IsSelected);
        lastSelectedItem.IsSelected = false;
        var lastSelectedItemIndex = AllCupTypeObservableCollection.IndexOf(lastSelectedItem);
        SetCupProperly(lastSelectedItem);
        AllCupTypeObservableCollection.Remove(lastSelectedItem);
        AllCupTypeObservableCollection.Insert(lastSelectedItemIndex, lastSelectedItem);
    }

    private static void SetCupProperly(CupVo vo)
    {
        if (vo.IsSelected)

            _ = vo.CupType switch
            {
                CupTypeEnum.自定 when vo.IsTitle => vo.Image = BitmapConstants.CupTypeActive,
                CupTypeEnum.自定 => vo.Image = BitmapConstants.CustomCupActive,
                CupTypeEnum.特大 => vo.Image = BitmapConstants.ExtremeBigCupActive,
                CupTypeEnum.大杯 => vo.Image = BitmapConstants.BigCupActive,
                CupTypeEnum.中杯 => vo.Image = BitmapConstants.MiddleCupActive,
                CupTypeEnum.小杯 => vo.Image = BitmapConstants.SmallCupActive,
                _ => throw new ArgumentOutOfRangeException()
            };
        else
            _ = vo.CupType switch
            {
                CupTypeEnum.自定 when vo.IsTitle => vo.Image = BitmapConstants.CupTypeInactive,
                CupTypeEnum.自定 => vo.Image = BitmapConstants.CustomCupInactive,
                CupTypeEnum.特大 => vo.Image = BitmapConstants.ExtremeBigCupInactive,
                CupTypeEnum.大杯 => vo.Image = BitmapConstants.BigCupInactive,
                CupTypeEnum.中杯 => vo.Image = BitmapConstants.MiddleCupInactive,
                CupTypeEnum.小杯 => vo.Image = BitmapConstants.SmallCupInactive,
                _ => throw new ArgumentOutOfRangeException()
            };
    }

    private Task ToggleAddColdWaterAsync(bool b)
    {
        IsAddWater = true;
        FormulaDetail.IsAddWater = true;
        IsAddColdWater = b;
        IsAddHotWater = !b;
        FormulaDetail.IsAddColdWater = b;
        FormulaDetail.IsAddHotWater = !b;
        return Task.CompletedTask;
    }

    private async Task SaveAndQuitAsync()
    {
        if (!ValidateData())
        {
            return;
        }

        var formulaCode = CustomCode + CupTypeCode + IceTypeCode + SugarTypeCode;
        if (!await CheckFormulaCodeIsUnique(formulaCode))
        {
            return;
        }

        await using var transaction = await _db.Database.BeginTransactionAsync();
        try
        {
            _formula ??= new Formula
            {
                Name = "",
                Code = "",
                AddWaterType = WaterTypeEnum.无,
                CupType = CupTypeEnum.特大,
                SugarType = SugarTypeEnum.零糖,
                IceType = IceTypeEnum.去冰
            };
            _formula.Name = FormulaDetail.Name!.Trim();
            _formula.SugarType = SelectedSugarType!.Value;
            _formula.CupType = SelectedCupType!.Value;
            _formula.IceType = SelectedIceType!.Value;
            _formula.AddWaterType = IsAddWater
                ? IsAddColdWater ? WaterTypeEnum.冰水 : WaterTypeEnum.热水
                : WaterTypeEnum.无;
            _formula.Code = formulaCode;
            _formula.HotWaterWeight = Convert.ToInt32(Math.Round(double.Parse(FormulaDetail.HotWaterWeight), 1) * 10);
            _formula.ColdWaterWeight = Convert.ToInt32(Math.Round(double.Parse(FormulaDetail.ColdWaterWeight), 1) * 10);
            _formula.IceWeight = Convert.ToInt32(Math.Round(double.Parse(FormulaDetail.IceWeight), 1) * 10);
            if (ActionType == ActionTypeEnum.修改)
            {
                //保存配方
                _db.Formulas.Update(_formula);
                //保存配方原料
                if (_formulaIngredientList.Count != 0)
                    _db.FormulaIngredients.RemoveRange(_formulaIngredientList);
                var insertList = FormulaDetail.IngredientAndWeightList
                    .Where(vo => vo.IngredientId != -1)
                    .Select(vo => new FormulaIngredient
                    {
                        FormulaId = _formula.Id,
                        IngredientId = vo.IngredientId,
                        Weight = Convert.ToInt32(Math.Round(double.Parse(vo.Weight) * 10, 1))
                    }).ToList();
                if (insertList.Count != 0)
                    await _db.FormulaIngredients.AddRangeAsync(insertList);
                await _db.SaveChangesAsync();
                await transaction.CommitAsync();
            }
            else if (ActionType == ActionTypeEnum.新建)
            {
                //保存配方
                await _db.Formulas.AddAsync(_formula);
                //获取Id
                await _db.SaveChangesAsync();
                //保存配方原料
                var insertList = FormulaDetail.IngredientAndWeightList
                    .Where(vo => vo.IngredientId != -1)
                    .Select(vo => new FormulaIngredient
                    {
                        FormulaId = _formula.Id,
                        IngredientId = vo.IngredientId,
                        Weight = Convert.ToInt32(Math.Round(double.Parse(vo.Weight) * 10, 1))
                    }).ToList();
                if (insertList.Count != 0)
                    await _db.FormulaIngredients.AddRangeAsync(insertList);
                await _db.SaveChangesAsync();
                await transaction.CommitAsync();
            }
            else if (ActionType == ActionTypeEnum.复制新建)
            {
                _formula.Id = default;
                //保存配方
                await _db.Formulas.AddAsync(_formula);
                //获取Id
                await _db.SaveChangesAsync();
                //保存配方原料
                var insertList = FormulaDetail.IngredientAndWeightList
                    .Where(vo => vo.IngredientId != -1)
                    .Select(vo => new FormulaIngredient
                    {
                        FormulaId = _formula.Id,
                        IngredientId = vo.IngredientId,
                        Weight = Convert.ToInt32(Math.Round(double.Parse(vo.Weight) * 10, 1))
                    }).ToList();
                if (insertList.Count != 0)
                    await _db.FormulaIngredients.AddRangeAsync(insertList);
                await _db.SaveChangesAsync();
                await transaction.CommitAsync();
            }

            AncestorScreen.Router.NavigateAndReset.Execute(new MainPageViewModel(AncestorScreen));
        }
        catch
        {
            await transaction.RollbackAsync();
            _ = MessageBoxUtil.GetBox("保存失败", "错误").ShowWindowAsync();
        }
    }

    private async Task<bool> CheckFormulaCodeIsUnique(string code)
    {
        var formula = await _db.Formulas.FirstOrDefaultAsync(formula => formula.Code.StartsWith(code.Substring(0, 3)));
        if (formula is null)
            return true;
        _ = MessageBoxUtil.GetBox($"配方码与配方[{formula.Name}]重复").ShowWindowAsync();
        return false;
    }

    private bool ValidateData()
    {
        if (string.IsNullOrWhiteSpace(CustomCode) || CustomCode.Length != 3 || !int.TryParse(CustomCode, out _))
        {
            MessageBoxUtil.GetBox("自定义的配方码必须为3位的数字").ShowWindowAsync();
            return false;
        }

        if (string.IsNullOrWhiteSpace(FormulaDetail.Name))
        {
            MessageBoxUtil.GetBox("配方名称不能为空").ShowWindowAsync();
            return false;
        }

        if (FormulaDetail.IngredientAndWeightList.All(vo => vo.IngredientId == -1))
        {
            MessageBoxUtil.GetBox("配方原料不能为空").ShowWindowAsync();
            return false;
        }

        var weightList = new List<string>(FormulaDetail.IngredientAndWeightList.Count + 3)
        {
            FormulaDetail.IceWeight,
            FormulaDetail.ColdWaterWeight,
            FormulaDetail.HotWaterWeight
        };
        if (weightList.Count(weight => weight.Equals("N", StringComparison.OrdinalIgnoreCase)) > 1)
        {
            MessageBoxUtil.GetBox("冷水、热水、冰块重量只能有一个为N").ShowWindowAsync();
            return false;
        }

        var exclude = weightList.FirstOrDefault(weight => weight.Equals("N", StringComparison.OrdinalIgnoreCase));
        if (exclude is not null)
            weightList.Remove(exclude);
        weightList.AddRange(FormulaDetail.IngredientAndWeightList.Select(vo => vo.Weight).ToList());
        if (!weightList.Any(weight => double.TryParse(weight, out _)))
        {
            MessageBoxUtil.GetBox("配方重量必须为数字").ShowWindowAsync();
            return false;
        }

        return true;
    }

    private Task CreateNewFormulaAsync()
    {
        _formula = new Formula
        {
            Name = "",
            Code = "",
            AddWaterType = WaterTypeEnum.无,
            CupType = CupTypeEnum.特大,
            SugarType = SugarTypeEnum.零糖,
            IceType = IceTypeEnum.去冰
        };
        FormulaDetail = new FormulaSaveOrUpdateVo();
        IsAddWater = FormulaDetail.IsAddWater;
        return Task.CompletedTask;
    }

    private async Task EditFormulaAsync(int formulaId)
    {
        _formula = await _db.Formulas.FirstAsync(formula => formula.Id == formulaId);
        CustomCode = _formula.Code[..3];
        await SetFormulaDetailAsync();
    }


    private async Task CopyCreateNewFormula(int formulaId)
    {
        _formula = await _db.Formulas.FirstAsync(formula => formula.Id == formulaId);
        await SetFormulaDetailAsync();
    }

    private async Task SetFormulaDetailAsync()
    {
        _formulaIngredientList = await _db.FormulaIngredients
            .Where(ingredient => ingredient.FormulaId == _formula!.Id)
            .ToListAsync();
        var ingredientIdArray = _formulaIngredientList
            .Select(ingredient => ingredient.IngredientId)
            .ToArray();
        var ingredientList = await _db.Ingredients
            .Where(ingredient => ingredientIdArray.Contains(ingredient.Id))
            .OrderBy(ingredient => ingredient.Id)
            .ToListAsync();
        FormulaDetail = new FormulaSaveOrUpdateVo
        {
            Name = _formula!.Name,
            SugarType = _formula.SugarType,
            CupType = _formula.CupType,
            IceType = _formula.IceType,
            ColdWaterWeight = Math.Round(_formula.ColdWaterWeight / 10.0, 1).ToString(CultureInfo.InvariantCulture),
            HotWaterWeight = Math.Round(_formula.HotWaterWeight / 10.0, 1).ToString(CultureInfo.InvariantCulture),
            IceWeight = Math.Round(_formula.IceWeight / 10.0, 1).ToString(CultureInfo.InvariantCulture)
        };
        SetAddWaterType();
        SetCupIceSugarType();
        SetIngredientDisplay(ingredientList.Select(ingredient => ingredient.Id).ToArray());
    }

    private void SetAddWaterType()
    {
        IsAddWater = _formula?.AddWaterType switch
        {
            WaterTypeEnum.无 => false,
            WaterTypeEnum.热水 => IsAddHotWater = true,
            WaterTypeEnum.冰水 => IsAddColdWater = true,
            _ => throw new ArgumentOutOfRangeException()
        };
    }

    private void SetIngredientDisplay(int[] ingredientIdArr)
    {
        FormulaDetail.IngredientAndWeightList =
            Ingredients.Where(vo => ingredientIdArr.Contains(vo.IngredientId)).ToList();

        var dic = _formulaIngredientList.ToDictionary(ingredient => ingredient.IngredientId);
        FormulaDetail.IngredientAndWeightList
            .ForEach(vo =>
            {
                vo.Weight =
                    Math.Round(dic[vo.IngredientId].Weight / 10.0, 1)
                        .ToString(CultureInfo.InvariantCulture);
            });
        while (FormulaDetail.IngredientAndWeightList.Count < 6)
        {
            FormulaDetail.IngredientAndWeightList.Add(new IngredientAndWeightVo
            {
                IngredientId = -1,
                IngredientName = "空"
            });
        }
    }

    private void SetCupIceSugarType()
    {
        SelectedCupType = _formula!.CupType;
        SelectedIceType = _formula.IceType;
        SelectedSugarType = _formula.SugarType;

        SugarTypeCode = Formula.GetSugarTypeCode(_formula.SugarType);
        CupTypeCode = Formula.GetCupTypeCode(_formula.CupType);
        IceTypeCode = Formula.GetIceTypeCode(_formula.IceType);

        var cupVo = _defaultCupList.First(vo => vo.IsTitle);
        cupVo.IsSelected = false;
        cupVo.Image = BitmapConstants.CupTypeInactive;
        var cupShouldActivated = _defaultCupList.First(vo => vo.CupType == _formula.CupType && !vo.IsTitle);
        cupShouldActivated.IsSelected = true;
        SetCupProperly(cupShouldActivated);

        var iceVo = _defaultIceList.First(vo => vo.IsTitle);
        iceVo.IsSelected = false;
        iceVo.Image = BitmapConstants.IceInactive;
        var iceShouldActivated = _defaultIceList.First(vo => vo.IceType == _formula.IceType && !vo.IsTitle);
        iceShouldActivated.IsSelected = true;
        SetIceProperly(iceShouldActivated);


        var sugarVo = _defaultSugarList.First(vo => vo.IsTitle);
        sugarVo.IsSelected = false;
        sugarVo.Image = BitmapConstants.SugarInactive;
        var sugarShouldActivated = _defaultSugarList.First(vo => vo.SugarType == _formula.SugarType && !vo.IsTitle);
        sugarShouldActivated.IsSelected = true;
        SetSugarProperly(sugarShouldActivated);
    }

    private List<IngredientAndWeightVo> GetIngredientList()
    {
        var ingredientList = _db.Ingredients
            .Select(ingredient => new IngredientAndWeightVo
            {
                IngredientId = ingredient.Id,
                IngredientName = ingredient.IngredientName,
            })
            .ToList();
        ingredientList.Add(new IngredientAndWeightVo
        {
            IngredientId = -1,
            IngredientName = "空"
        });
        return ingredientList;
    }
}

/// <summary>
/// 默认杯子、糖、冰类型
/// </summary>
public partial class FormulaSaveOrUpdateViewModel
{
    private readonly List<CupVo> _defaultCupList =
    [
        new CupVo
        {
            Image = BitmapConstants.CupTypeActive,
            IsSelected = true,
            IsTitle = true,
            CupType = CupTypeEnum.自定
        },
        new CupVo
        {
            Image = BitmapConstants.ExtremeBigCupInactive,
            IsSelected = false,
            IsTitle = false,
            CupType = CupTypeEnum.特大
        },
        new CupVo
        {
            Image = BitmapConstants.BigCupInactive,
            IsSelected = false,
            IsTitle = false,
            CupType = CupTypeEnum.大杯
        },
        new CupVo
        {
            Image = BitmapConstants.MiddleCupInactive,
            IsSelected = false,
            IsTitle = false,
            CupType = CupTypeEnum.中杯
        },
        new CupVo
        {
            Image = BitmapConstants.SmallCupInactive,
            IsSelected = false,
            IsTitle = false,
            CupType = CupTypeEnum.小杯
        },
        new CupVo
        {
            Image = BitmapConstants.CustomCupInactive,
            IsSelected = false,
            IsTitle = false,
            CupType = CupTypeEnum.自定
        }
    ];

    private readonly List<SugarVo> _defaultSugarList =
    [
        new SugarVo
        {
            SugarType = SugarTypeEnum.全糖,
            Image = BitmapConstants.FullSugarActive,
            IsSelected = true,
            IsTitle = true
        },
        new SugarVo
        {
            SugarType = SugarTypeEnum.零糖,
            Image = BitmapConstants.NoSugarInactive,
            IsSelected = false,
            IsTitle = false
        },
        new SugarVo
        {
            SugarType = SugarTypeEnum.三分,
            Image = BitmapConstants.ThreeSugarInactive,
            IsSelected = false,
            IsTitle = false
        },
        new SugarVo
        {
            SugarType = SugarTypeEnum.五分,
            Image = BitmapConstants.FiveSugarInactive,
            IsSelected = false,
            IsTitle = false
        },
        new SugarVo
        {
            SugarType = SugarTypeEnum.七分,
            Image = BitmapConstants.SevenSugarInactive,
            IsSelected = false,
            IsTitle = false
        },
        new SugarVo
        {
            SugarType = SugarTypeEnum.全糖,
            Image = BitmapConstants.FullSugarInactive,
            IsSelected = false,
            IsTitle = false
        },
    ];

    private readonly List<IceVo> _defaultIceList =
    [
        new IceVo
        {
            IceType = IceTypeEnum.无冰,
            Image = BitmapConstants.IceActive,
            IsSelected = true,
            IsTitle = true
        },
        new IceVo
        {
            IceType = IceTypeEnum.去冰,
            Image = BitmapConstants.StripIceInactive,
            IsSelected = false,
            IsTitle = false
        },
        new IceVo
        {
            IceType = IceTypeEnum.少冰,
            Image = BitmapConstants.LittleIceInactive,
            IsSelected = false,
            IsTitle = false
        },
        new IceVo
        {
            IceType = IceTypeEnum.正常,
            Image = BitmapConstants.NormalInactive,
            IsSelected = false,
            IsTitle = false
        },
        new IceVo
        {
            IceType = IceTypeEnum.常温,
            Image = BitmapConstants.NormalTemperatureInactive,
            IsSelected = false,
            IsTitle = false
        },
        new IceVo
        {
            IceType = IceTypeEnum.无冰,
            Image = BitmapConstants.NoIceInactive,
            IsSelected = false,
            IsTitle = false
        },
    ];
}